<template>
    <MenuPage 
      ref="selectTable"
      :data="imageList" 
      :columns="imageCol"
      :page.sync="imagePage"
      :size.sync="imagePageSize"
      :total="imageTotal"
      :loading="imageListLoading"
      showSelectTag
      selectName="imageName"
      :selection.sync="selectImages" 
      @queryFun="getImageList">
      <template slot="search">
          <Button ghost style="margin-right: 15px" type="primary" icon="ios-cloud-upload-outline" v-if="distributed" @click="reportedImages">镜像上报</Button>
          <Button type="primary" ghost class="md-add-jh" @click="creatImage">创建镜像</Button>
          <Divider type="vertical" style="margin: 10px 0px 10px 10px;" />
          <div style="height: 32px;line-height: 32px;margin-left: 15px">
            <Checkbox v-model="creatByMeModal" @on-change="searchCreatedByMe" style="width:70px;">由我创建</Checkbox>
          </div>
          <Select filterable @on-change="searchItem" v-model="rangeId" style="width:155px" :placeholder="'靶场:'+mainRange" clearable v-if="distributedRange">
            <Option v-for='(items,index) in rangeAllList' :value="items.id" :key="index+'range'">{{items.name}}</Option>
          </Select>
          <i-select clearable v-model="imageLocalvisibility" placeholder="可见范围" style="margin-left: 15px;width: 150px" @on-change="selectImageTypeChange">
            <i-option value="range">平台</i-option>
            <i-option value="system">系统</i-option>
            <i-option value="company">单位</i-option><i-option value="person">个人</i-option>
          </i-select>
          <i-select clearable v-model="systemType" @on-change="selectsystemType" placeholder="系统类型" style="margin-left: 15px;width: 150px">
            <i-option value="linux">linux</i-option>
            <i-option value="windows">windows</i-option>
            <!-- <i-option value="unix">unix</i-option>
            <i-option value="windows7">windows7</i-option>
            <i-option value="windows2003">windows2003</i-option>
            <i-option value="windowsXP">windowsXP</i-option> -->
          </i-select>
          <i-select clearable v-model="virtualization" @on-change="selectvtype" placeholder="虚拟化类型" style="margin-left: 15px;width: 150px">
            <i-option value="kvm">kvm</i-option>
            <i-option value="docker">docker</i-option>
            <!-- <i-option value="linux">unix</i-option> -->
          </i-select>
          <Input v-model.trim="imageModelInput" clearable placeholder="镜像名称" @on-change="searchImageNameBtn" style="width: 180px;margin-left: 15px" />
          <Button class="header-btn" type="primary" ghost style="height: 32px;margin-left: 5px;" @click="refreshImage()">
            <i class="el-icon-refresh-right" />
          </Button>
      </template>
    <!--创建镜像"-->
    <Modal v-model="imageModal" :mask-closable="false" width="600" @on-visible-change="watchModalStatus" :footer-hide="true" :title="modalTitle">
      <Form ref="imageFormData" :model="imageFormData" :rules="creatImageRuleValidate" :label-width="120" style="width: 500px">
        <FormItem label="系统类型" prop="osType">
          <Select filterable v-model="imageFormData.osType" placeholder="选择系统类型" @on-change="() => {
            imageFormData.osVersion =''
            getImageType()
          }">
            <Option value="windows">Windows</Option>
            <Option value="linux">Linux</Option>
            <!-- <Option value="windows2003">Windows2003</Option>
            <Option value="windows7">Windows7</Option>
            <Option value="windowsXP">WindowsXP</Option>
            <Option value="unix">Unix</Option> -->
          </Select>
        </FormItem>
        <FormItem label="虚拟化类型" prop="virtualization">
          <!-- <RadioGroup v-model="imageFormData.virtualization">
            <Radio label="kvm">Kvm</Radio>
            <Radio label="docker">Docker</Radio>
          </RadioGroup> -->
           <Select filterable v-model="imageFormData.virtualization" placeholder="请选择虚拟化类型" @on-change="(val) => {
            {
            imageFormData.osVersion =''
            getImageType()
            getImagevirtualizatione(val)
          }
           }">
              <Option value="kvm">kvm</Option>
              <Option value="docker">docker</Option>
            </Select>
        </FormItem>
        <FormItem label="系统版本" prop="osVersion" v-if="imageFormData.virtualization==='kvm'">
            <Select filterable v-model="imageFormData.osVersion" filterable placeholder="选择系统版本">
              <Option v-for="(item,index) in systemVersion" :key="item.uuid" :value="item.operatingSystem">{{item.operatingSystem}}</Option>
            </Select>
        </FormItem>
        <FormItem label="名称" prop="imageName">
          <div style="display: flex;justify-content: flex-start;width: 580px;">
            <Input v-model.trim="imageFormData.imageName" placeholder="名称" style="width:380px"></Input>
            <Tooltip v-if="imageFormData.virtualization == 'docker'" style="margin-left: 10px;" :transfer='true' max-width="200" content="docker类型镜像,镜像名称和源镜像名称需要保持一致,否则会导致镜像无法正常使用" placement="top">
              <Icon type="ios-alert" class="ios-alert" />
            </Tooltip>
          </div>
          <!-- <p style="color:#f90" v-if="imageFormData.virtualization == 'docker'"><Icon type="ios-information-circle-outline" />docker类型镜像,镜像名称和源镜像名称需要保持一致,否则会导致镜像无法正常使用</p> -->
        </FormItem>
        <FormItem label="硬盘最小值(GB)" prop="minDisk">
          <InputNumber :max="1024" :min="1" :step="1" v-model="imageFormData.minDisk" style="width: 130px"></InputNumber>
        </FormItem>
        <FormItem label="内存最小值(MB)" prop="minRam">
          <InputNumber :max="65536" :min="128" :step="1" v-model="imageFormData.minRam" style="width: 130px"></InputNumber>
        </FormItem>
        <FormItem label="Profile" prop="profileId">
          <div style="display: flex;justify-content: flex-start;width: 580px;">
            <Select filterable v-model="imageFormData.profileId" placeholder="请选择profile" style="width: 380px;" @on-change="getProfileName">
              <Option :value="value.id" v-for="(value,index) in profileList" :key="index" :title="value.osName">{{value.osName}}</Option>
            </Select>
            <Tooltip style="margin-left: 10px;" :transfer='true' max-width="200" content="带外采集专用参数，制作镜像时没有配置此项，上传的镜像不支持带外采集无需配置" placement="top">
              <Icon type="ios-alert" class="ios-alert" />
            </Tooltip>
          </div>
        </FormItem>
        <FormItem label="可见范围" prop="visibility">
          <RadioGroup v-model="imageFormData.visibility">
            <Radio label="share">单位</Radio>
            <Radio label="private">个人</Radio>
          </RadioGroup>
        </FormItem>
        <FormItem label="设备类型" prop="nodeType" >
          <Select filterable v-model="imageFormData.nodeType" placeholder="选择设备类型" multiple>
            <Option value="vm">VM</Option>
            <Option value="firewall">firewall</Option>
            <Option value="ids">IDS</Option>
            <Option value="waf">WAF</Option>
            <Option value="drout">Drout</Option>
            <Option value="des">DES:离散事件仿真节点</Option>
            <Option value="base">BASE</Option>
          </Select>
        </FormItem>
        <FormItem label="网卡型号" prop="hwVifModel" v-show='!isCreate'>
          <Select filterable v-model="imageFormData.hwVifModel" placeholder="选择网卡型号">
            <Option value="virtio">virtio</Option>
            <Option value="e1000">e1000</Option>
            <Option value="rtl8139">rtl8139</Option>
          </Select>
        </FormItem>
        <FormItem label="硬盘型号" prop="hwDiskBus" v-show='!isCreate'>
          <Select filterable v-model="imageFormData.hwDiskBus" placeholder="选择硬盘型号">
            <Option value="virtio">virtio</Option>
            <Option value="scsi">scsi</Option>
            <Option value="ide">ide</Option>
          </Select>
        </FormItem>
        <FormItem label="HasQga" prop="hasQga">
          <i-switch v-model="imageFormData.hasQga" size="large">
            <span slot="open">是</span>
            <span slot="close">否</span>
          </i-switch>
          <Tooltip style="margin-left: 10px;" :transfer='true' max-width="200" content="镜像是否有qga插件" placement="top">
            <Icon type="ios-alert" class="ios-alert" />
          </Tooltip>
        </FormItem>
        <FormItem label="HasVirtioDriver" prop="hasVirtoDriver">
          <i-switch v-model="imageFormData.hasVirtoDriver" size="large">
            <span slot="open">是</span>
            <span slot="close">否</span>
          </i-switch>
          <Tooltip style="margin-left: 10px;" :transfer='true' max-width="200" content="镜像是否有virto驱动" placement="top">
            <Icon type="ios-alert" class="ios-alert" />
          </Tooltip>
        </FormItem>
        <!-- <FormItem label="HasHtPlug" prop="htPlug">
          <i-switch v-model="imageFormData.htPlug" size="large">
            <span slot="open">是</span>
            <span slot="close">否</span>
          </i-switch>
          <Tooltip style="margin-left: 10px;" :transfer='true' max-width="200" content="镜像是否支持合天插件" placement="top">
            <Icon type="ios-alert" class="ios-alert" />
          </Tooltip>
        </FormItem> -->
        <FormItem label="HasCloudInit" prop="hasCloudInit">
          <i-switch v-model="imageFormData.hasCloudInit" size="large">
            <span slot="open">是</span>
            <span slot="close">否</span>
          </i-switch>
          <Tooltip style="margin-left: 10px;" :transfer='true' max-width="200" content="镜像是否支持cloud注入" placement="top">
            <Icon type="ios-alert" class="ios-alert" />
          </Tooltip>
        </FormItem>
        <FormItem v-show="showUploadFile" label="上传文件" class="ivu-form-item ivu-form-item-required" prop="file">
          <Upload v-model="imageFormData.file" :action="updateUrl" :before-upload="handleUpload">
            <Button icon="ios-cloud-upload-outline" :disabled="setDisabled">选择文件</Button>
          </Upload>
          <Tooltip class="too" style="margin-left: 10px;" :transfer='true' max-width="240" :content="imageFormData.virtualization=='kvm'?'kvm类型文件格式为 XX.qcow2':'docker类型文件格式为 XX.docker  和 XXX.tar'" placement="top">
            <Icon type="ios-alert" class="ios-alert" />
          </Tooltip>
          <div v-if="progressflag">
            <p>文件名: {{ fileName }}</p>
            <p>文件大小:<span v-text="fileSize"></span></p>
            <Progress :percent="progress"></Progress>
            <p>上传速度:<span v-text="speed"></span></p>
          </div>
        </FormItem>
        <FormItem label="描述" prop="description">
          <Input v-model.trim="imageFormData.description" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="描述" :maxlength="200"></Input>
        </FormItem>
        <FormItem>
          <Button type="primary" @click="submitBtn('imageFormData')" :loading="addImageBtnLoading" :disabled="setDisabled">确定</Button>
          <Button @click="creatImageHandleReset('imageFormData')" style="margin-left: 8px">重置</Button>
        </FormItem>
      </Form>
    </Modal>
    <!-- 镜像信息 -->
    <Modal v-model="styState" title="镜像详情" :mask-closable="false" :width="800" footer-hide>
      <div id="quesDetail">
        <p><span class='label'>镜像名称</span><span>{{systemData.imageName}}</span></p>
        <p><span class='label'>镜像ID</span><span>{{systemData.id}}</span></p>
        <p><span class='label'>创建者</span><span>{{systemData.creatorName}}</span></p>
        <p><span class='label'>镜像大小(GB)</span><span>{{getGb(systemData.imageSize)}}</span></p>
        <p><span class='label'>硬盘(GB)</span><span>{{systemData.minDisk}}</span></p>
        <p><span class='label'>内存(MB)</span><span>{{systemData.minRam}}</span></p>
        <p><span class='label'>Profile</span><span>{{systemData.profileName }}</span></p>
        <p><span class='label'>系统类型</span><span>{{systemData.osType }}</span></p>
        <p><span class='label'>虚拟化类型</span><span>{{systemData.virtualization}}</span></p>
        <p><span class='label'>可见范围</span><span :style="{color:setVisibility(systemData.visibility).color}">{{setVisibility(systemData.visibility).text}}</span></p>
        <p><span class='label'>设备类型</span><span>{{systemData.nodeType}}</span></p>
        <p v-if='systemData.hwVifModel'><span class='label'>网卡型号</span><span>{{systemData.hwVifModel}}</span></p>
        <p v-if='systemData.hwDiskBus'><span class='label'>硬盘型号</span><span>{{systemData.hwDiskBus}}</span></p>
        <p><span class='label'>HasQga</span><span>{{systemData.qga ? '是' : '否'}}</span></p>
        <p><span class='label'>HasVirtoDriver</span><span>{{systemData.virtio ? '是' : '否'}}</span></p>
        <!-- <p><span class='label'>HasHtPlug</span><span>{{systemData.htPlug}}</span></p>  -->
        <p><span class='label'>HasCloudInit</span><span>{{systemData.cloud ? '是' : '否'}}</span></p>
        <p><span class='label'>创建时间</span><span>{{systemData.created}}</span></p>
        <p><span class='label'>描述</span><span>{{systemData.description}}</span></p>
      </div>
    </Modal>
    <!-- 镜像接入信息 -->
    <Modal v-model="showImgUser" width="800" title="镜像接入用户管理" :footer-hide='true'>
      <div style="display: flex;justify-content: flex-end;margin-bottom: 10px;">
        <Button type="primary" @click='showForm'>
          <Icon type="md-add" size="large" />增加接入账号
        </Button>
      </div>
      <TableList :columns="accessCol" :data="imgUserList" style="margin-bottom: 20px;"></TableList>
      <Form ref="formV" :model="formV" :rules="ruleV" :label-width="120" style="width: 500px;" v-show='formIsShow'>
        <FormItem label="用户名" prop="userName">
          <Input name="userName" v-model.trim="formV.userName" placeholder="用户名"></Input>
        </FormItem>
        <FormItem label="密码类型" prop="pwdType">
          <RadioGroup v-model="formV.pwdType">
            <Radio :disabled="!isClound" label="cloud"><span>cloud</span></Radio>
            <Radio label="static"><span>static</span></Radio>
            <Radio label="local"><span>local</span></Radio>
          </RadioGroup>
        </FormItem>
        <FormItem v-if="formV.pwdType === 'static'" label="密码" prop="password">
          <i-Input v-model.trim="formV.password" placeholder="密码"></i-Input>
        </FormItem>
        <FormItem label="接入类型" prop="accessType">
          <RadioGroup v-model="formV.accessType" @on-change="setUserPort">
            <Radio label="ssh"></Radio>
            <Radio label="rdp"></Radio>
            <Radio label="console"></Radio>
            <Radio label="telnet"></Radio>
          </RadioGroup>
        </FormItem>
        <FormItem v-if="formV.accessType !== 'console'" label="端口" prop="port">
          <i-Input type="text" v-model.trim="formV.port" :placeholder="createPort"></i-Input>
        </FormItem>
        <FormItem>
          <Button type="primary" @click="addOrModify('formV')" :loading='addUserLoading'>确定</Button>
          <Button style="margin-left: 8px" @click="resetAddUser('formV')">重置</Button>
        </FormItem>
      </Form>
    </Modal>
  <!-- </div> -->
</MenuPage>
</template>
<script>
function getGb (val) {
  let floatNum = parseInt(val) / (1024 * 1024 * 1024)
  floatNum = floatNum.toFixed(2)
  return floatNum
}
import $ from 'jquery'
import encryption from '@/libs/encryption.js'
import { mapState } from 'vuex'
import { getImageData, deleteImage, getProfile, modifyImg, getDetailByID, getImageUserList, addAccess, modifyAccess, delAccess, mergeFiles, checkImage,getImageType } from '@/api/image.js'
import { getOperateInfo } from '@/api/target.js'
import { validateName,validateName128 } from '@/libs/reg'
import { reportedImages, getRangeAll } from '@/api/reported-data'
import resourcesReportedMixin from '@/mixin/resources-reported-mixin'
import pageTitle from '@/mixin/pageTitle';
import {
    SYSTEM_TYPE,
    VIRTUALIZATION_TYPE,
    NODE_TYPE,
    ACCESS_TYPE,
    PASSWORD_TYPE
} from '@/libs/format';
const validateMinram = (rule, value, callback) => {
  let reg = /^\d+$/;
  if (reg.test(value)) {
    let val = parseInt(value)
    if (val >= 128 && val <= 65536) {
      return callback()
    } else {
      return callback(new Error('内存大小为128MB到65536MB之间'))
    }
  } else {
    return callback(new Error('请输入整数'))
  }

}
// const validateName = (rule, value, callback) => { //验证只能填入数字
//     var reg = new RegExp("^[\/\u4E00-\u9FA5\(\)a-zA-Z0-9_-]*$");
//     //验证警戒值
//     if(value){
//         if (!reg.test(value)) {
//             callback(new Error('请输入中文、数字、字母、英文括号、下划线或者中划线'));
//         }else{
//             callback()
//         }
//     }else{
//         callback()
//     }
// }

const validateMindisk = (rule, value, callback) => {
  let reg = /^\d+$/;
  if (reg.test(value)) {
    let val = parseInt(value)
    if (val >= 1 && val <= 1024) {
      return callback()
    } else {
      return callback(new Error('硬盘大小为1GB到1024GB之间'))
    }
  } else {
    return callback(new Error('请输入整数'))
  }

}
const validatePort = (rule, value, callback) => { //验证只能填入数字
  var reg = new RegExp("^(([1-9]\\d{0,3})|([1-5]\\d{4})|(6[0-4]\\d{3})|(65[0-4]\\d{2})|(655[0-2]\\d)|(6553[0-5]))$");
  //验证警戒值
  if (value) {
    if (!reg.test(Number(value))) {
      callback(new Error('请输入1-65535的整数'));
    } else {
      callback()
    }
  } else {
    callback()
  }
}
export default {
  components: {},
  mixins: [resourcesReportedMixin,pageTitle],
  data () {
    let regPasswd = /^[0-9a-zA-Z_]{8,16}$/;   // 密码是数字 字母 或者下划线的组合
    const validatePass = (rule, value, callback) => {
      if (regPasswd.test(value)) {
        callback();
      } else {
        callback(new Error('密码是字母、数字或下划线的组合，长度为8—16位'));
      }
    };
    // 判断是否包含空格
    const ifHasSpace = function (str) {
      if (str.indexOf(' ') === -1) {
        // 没有空格
        return true
      } else {
        // 有空格
        return false
      }
    }
    const validSpace = function (rule, value, callback) {
      if (ifHasSpace(value)) {
        callback()
      } else {
        callback(new Error())
      }
    }
    return {
      mainRangeflag:true,
      mainRange:'',
      rangeId: '',
      rangeAllList: [],
      selectImages: [],
      selectAllImages: false,
      modalTitle: '创建镜像',
      styState: false,
      systemData: {},//详情内容
      // 用户信息
      USER_ID: '',
      isRootDesinger: '',
      distributed: false,
      //分布式主靶场
      // distributedRange:false,
      // 页面设置
      fullHeight: document.documentElement.clientHeight,
      fullWidth: document.documentElement.clientWidth,
      setTableHei: 'auto',
      showDefImg: false,
      showImgList: false,
      // 镜像列表
      imageListLoading: false,
      imageLocalvisibility: '',
      systemType: '',
      virtualization: '',
      imageTotal: 0,
      imageList: [],
      imageCol: [
        {
            type: 'selection',
            width: 60,
            align: 'left',
            show:() => {
              return this.distributed
            }
        },
        {
            type: 'link',
            title: '镜像名称',
            key: 'imageName',
            tooltip: true,
            on:{
              click:(data) => {
                this.openSystem(data)
              }
            },
            minWidth: 100
        },
        {
            title: '镜像大小(GB)',
            key: 'imageSize',
            filter: this.getGb,
            tooltip: true,
            minWidth:100,
        },
        {
            title: '镜像配置',
            key: 'osType',
            minWidth: 280,
            tooltip:true,
            filter: (osType, data) => {
                return `系统类型：${osType || '-'} / 系统版本：${data.osVersion || '-'} / Disk:${data.minDisk}GB / RAM:${
                    data.minRam
                }MB`;
                // return `${SYSTEM_TYPE[osType] || '-'} / Disk:${data.minDisk}GB / RAM:${
                //     data.minRam
                // }MB`;
            }
        },
        // {
        //     title: '系统类型',
        //     key: 'osType',
        //     tooltip: true,
        //     minWidth:50,
            // filter: (osType) => {
            //     return SYSTEM_TYPE[osType];
            // }
        // },
        // {
        //   title:'系统版本',
        //   key:'osVersion',
        //   tooltip: true,
        //   minWidth:50,
        // },
        // {
        //     title: '硬盘(GB)',
        //     key: 'minDisk',
        //     tooltip: true,
        //     minWidth:50
        // },
        // {
        //     title: '内存(MB)',
        //     key: 'minRam',
        //     tooltip: true,
        //     minWidth:50
        // },
        {
            title: '虚拟化类型',
            key: 'virtualization',
            tooltip: true,
            minWidth:100
            // filter: (virtualization) => {
            //     return VIRTUALIZATION_TYPE[virtualization];
            // }
        },
        {
            title: '创建状态',
            key: 'statusCHName',
            tooltip: true,
            minWidth:100,
            // show:() => {
            //   return false
            // },
            setColor: (statusCHName, data) => {
                return this.setColor(data);
            }
        },
        {
            title: '验证状态',
            width: 100,
            key: 'statusName',
            show:() => {
              return false
            },
            render: (h, params) => {
                let item = params.row;
                return h(
                    'Tooltip',
                    {
                        props: {
                            disabled: item.verify !== 'error' && item.verify !== 'active',
                            placement: 'top',
                            'max-width': '600'
                        },
                        on: {
                            'on-popper-show': () => {
                                this.changeSwitch(item);
                            },
                            'on-popper-hide': () => {
                                this.changeFlag(item);
                            }
                        }
                    },
                    [
                        h(
                            'span',
                            {
                                style: { color: this.setScriptColor(item) },
                                on: {
                                    mouseover: () => {
                                        this.mouseOver(item);
                                    }
                                }
                            },
                            item.statusName
                        ),
                        h('Table', {
                            slot: 'content',
                            props: {
                                columns: this.columns1,
                                data: this.data1,
                                style: {
                                    display: this.messageSwitch ? 'block' : 'none',
                                    'white-apace': 'normal',
                                    'word-break': 'break-all',
                                    width: '560px'
                                }
                            }
                        })
                    ]
                );
            }
        },
        {
            title: '可见范围',
            key: 'visibility',
            minWidth:100,
            filter: (visible, data) => {
                return this.setVisibility(visible).text
                // return this.filterVisible(visible, 'text');
            },
            setColor: (visible, data) => {
                return this.setVisibility(visible).color
                // return this.filterVisible(visible, 'color');
            }
        },
        {
          title:'上报状态',
          key:'reportedStatus',
          show:() => {
            return this.distributed
          },
          filter:(reportedStatus) => {
            return ['0', '1'].includes(reportedStatus)
              ? '上报失败'
              : reportedStatus === '2'
              ? '上报成功'
              : '未上报'
          },
          setColor:(reportedStatus) => {
            return ['0', '1'].includes(reportedStatus)
              ? 'var(--status-no)'
              : reportedStatus === '2'
              ? 'var(--status-yes)'
              : 'var(--status-pre)'
          },
          disabled:(data) => {
            return !['0', '1'].includes(data.reportedStatus)
          },
          tooltip:true,
          tooltipKey:'reportedMsg',
          minWidth:100,
        },
        { title: '创建者', key: 'creatorName', minWidth:100,tooltip: true },
        { title: '创建时间', key: 'created',minWidth:100, tooltip: true },
        {
            title: '操作',
            width: 240,
            slot: 'action',
            opList: [
                {
                    txt: '验证',
                    on:{
                      click:(data,e) => {
                        this.check(data)
                      }
                    },
                    show:() => {
                      return false
                    }
                },
                {
                    txt: '镜像接入用户',
                    on:{
                      click:(data,e) => {
                        this.imageUserBtn(data)
                      }
                    },
                    disabled: this.setIsClick
                },
                {
                    txt: '修改',
                    on:{
                      click:(data,e) => {
                        this.modifyImage(data)
                      }
                    },
                    disabled: this.setIsClick
                },
                {
                    txt: '删除',
                    tooltip: true,
                    type: 'delete',
                    title: '确定要删除这个镜像吗？',
                    on:{
                      click:(data,e) => {
                        this.delImg(data)
                      }
                    },
                    disabled: this.setIsClick
                }
            ]
        }
    ],
      imagePage: 1,
      imagePageSize: 10,
      searchImageName: '',
      imageModelInput: '',
      creatByMeModal: false,
      // 创建和修改镜像
      imageID: '',
      imageModal: false,
      updateUrl: `/api/resource-manager/image/add`,
      addImageBtnLoading: false,
      imageFormData: {
        imageName: '',
        minDisk: 0,
        minRam: 0,
        profileId: '',
        profileName: '',
        osType: 'windows',
        virtualization: 'kvm',
        osVersion:'',
        visibility: 'share',
        nodeType: '',
        hasQga: false,
        hasVirtoDriver: false,
        htPlug: false,
        hasCloudInit: false,
        description: '',
        file: null,
        hwVifModel: '',
        hwDiskBus: '',
        tempId: ''
      },
      creatImageRuleValidate: {
        imageName: [
          { required: true, message: '名称不能为空', trigger: 'change' },
          { max: 128, message: '名称长度不能超过128个字符', trigger: 'change' },
          { validator: validateName128, trigger: 'change' }
        ],
        virtualization: [
          { required: true, message: '虚拟化类型不能为空', trigger: 'change' }
        ],
        osVersion: [
          { required: true, message: '系统版本不能为空', trigger: 'change' }
        ],
        visibility: [
          { required: true, message: '可见范围不能为空', trigger: 'change' }
        ],
        nodeType: [
          { required: true, message: '设备类型不能为空', trigger: 'change', type: 'array' }
        ],
        osType: [
          { required: true, message: '系统类型不能为空', trigger: 'change' }
        ],
        minRam: [
          { required: true, validator: validateMinram, min: 128, max: 65536, trigger: 'change' },
        ],
        minDisk: [
          { required: true, validator: validateMindisk, min: 1, max: 1024, trigger: 'change' },
        ],
        description: [
          { max: 200, message: '描述长度不能超过200个字符', trigger: 'change' },
        ],
      },
      speed: 0,
      loaded: 0,
      fileSize: 0,
      progress: 0,
      setDisabled: false,
      // 判断状态
      showUploadFile: true,
      isCreate: true,
      //profile
      profileList: [],
      // 镜像用户
      showImgUser: false,
      formIsShow: false,
      imageUserId: '',
      addUserLoading: false,
      createPort: '22',
      isCreatUser: false,
      isClound: false,
      imgUserList: [],
      flag: 0, //标记成功的次数
      filedArr: [],//承装切片的容器
      oldTime: 0,//初始化时间
      progressflag: false,//控制进度条的展示
      fileName: '',
      proSetInterval: '',//定时器
      saveTargetStatusArr: [],//存储中间状态
      messageSwitch: false,//解决鼠标移入失败或者成功验证状态气泡框位置错乱设置的开关
      accessCol: [
        {
          type: 'index',
          align: 'center',
          width: 60
        },
        {
          title: '用户名',
          key: 'userName',
          align: 'center',
        },
        {
          title: '密码',
          key: 'password',
          align: 'center',
        },
        {
          title: '接入类型',
          key: 'accessType',
          align: 'center',
        },
        {
          title: '端口',
          key: 'port',
          align: 'center',
        },
        {
          title: '密码类型',
          key: 'pwdType',
          align: 'center',
          // render: (h, params) => {
          //   let pwdType = params.row.pwdType
          //   return h('span', pwdType == 'cloud' ? "主动配置" : "系统内置")
          // }
        },
        {
          title: '操作',
          key: 'action',
          width: 100,
          opList:[
            {
              txt:'修改',
              fun:this.modifyAssBtn
            },
            {
              txt:'删除',
              type:"delete",
              title: '确定要删除吗？',
              tooltip:true,
              fun:(data) => {
                this.delAccess(data.id)
              }
            }
          ],
          // render: (h, params) => {
          //   return h('div', {
          //     style: {
          //       'display': 'flex',
          //       'justify-content': 'flex-start',
          //       'align-items': 'center',
          //     },
          //   }, [
          //     h('Poptip',
          //       {
          //         props: {
          //           confirm: true,
          //           transfer: true,
          //           title: '确定要删除吗？'
          //         },
          //         on: {
          //           'on-ok': () => {
          //             this.delAccess(params.row.id)
          //           },
          //           'on-cancel': () => {

          //           }
          //         }
          //       },
          //       [
          //         h('img', {
          //           attrs: {
          //             src: require('../../assets/project/dels-h.png'),
          //             title: '删除'
          //           },
          //           style: {
          //             cursor: 'pointer',
          //             'margin-right': '5px',
          //             'vertical-align': 'middle',
          //             width: '22px',
          //             height: '22px',
          //             display: 'inline-block',
          //           },
          //         }),
          //       ],
          //     ),
          //     h('div', {
          //       on: {
          //         'click': () => {
          //           this.modifyAssBtn(params.row)
          //         },
          //       },
          //       style: {
          //         'margin-left': '15px',
          //       }
          //     }, [
          //       h('img', {
          //         attrs: {
          //           src: require('../../assets/project/modifys-h.png'),
          //           title: '修改'
          //         },
          //         style: {
          //           cursor: 'pointer',
          //           'margin-right': '5px',
          //           'vertical-align': 'middle',
          //           width: '22px',
          //           height: '22px',
          //           display: 'inline-block',
          //         },
          //       }),
          //     ])
          //   ])
          // }
        },
      ],
      // 接入用户表单
      formV: {
        accessType: "ssh",
        password: "",
        imageId: "",
        port: '',
        pwdType: "static",
        userName: "",
        id: '',
      },
      ruleV: {
        userName: [
          { required: true, type: 'string', min: 1, max: 15, message: '用户名的长度为1到15个字符', trigger: 'change' },
        ],
        password: [
          // { required: true, validator: validatePass, trigger: 'blur' },
          // { validator: validSpace, message: '字符不能包含空格', trigger: 'blur' },
          // { type: 'string', min: 8, max: 16, message: '密码不能为空', trigger: 'blur' }
          {required: true, message: '密码不能为空', trigger: 'blur' },
          {validator: validSpace, message: '字符不能包含空格', trigger: 'blur' },
          {type: 'string', min: 6, max: 16, message: '密码密码长度为6-16位', trigger: 'blur' }
        ],
        pwdType: [
          { required: true, message: '请选择密码类型', trigger: 'change' }
        ],
        accessType: [
          { required: true, message: '请选择接入类型', trigger: 'change' }
        ],
        port: [
          { required: true, message: '端口不能为空', trigger: 'change' },
          { validator: validatePort, trigger: 'change' }
        ]
      },
      columns1: [
        {
          title: '测试项',
          align: 'center',
          key: 'testItemName'
        },
        {
          title: '是否成功',
          align: 'center',
          key: 'isSuccess',
          width: 160,
          render: (h, params) => {
            return h('span', params.row.isSuccess ? '是' : '否')
          }
        },
        {
          title: '信息',
          align: 'center',
          minWidth: 120,
          key: 'message'
        }
      ],
      data1: [],
      systemVersion:[]
    }
  },
  computed: {
    ...mapState('board', ['newNotice']), //新消息
    distributedRange () {
      return this.$store.state.user.distributedRange
    }
  },
  watch: {
    newNotice (val) {
      if (val.title) { // 收到镜像创建成功的公告，刷新镜像列表
        let reg = /^创建镜像.*成功$/
        if (reg.test(val.title)) {
          this.refreshImage()
        }
      }
    },
    showImgUser (val) {
      if (!val) {
        this.resetAddUser('formV')
      }
    }
  },
  created () {
    // 获取用户id
    let November = sessionStorage.getItem('November')
    November = JSON.parse(encryption.SelfUseDecrypt(November))
    this.USER_ID = November.userId
    this.isRootDesinger = November.isRootDesinger
    this.distributed = November.distributed
    // this.distributedRange = this.$store.state.user.distributedRange
  },
  mounted () {
    // this.setStyle()
    // window.onresize = () => {
    //   this.setStyle()
    // }
    let getPage = this.$route.query.page ? parseInt(this.$route.query.page) : 1
    this.imagePage = getPage
    this.getImageList()
    this.queryAllRange()
    this.getImageType()
  },
  methods: {
    getImagevirtualizatione(val){
      console.log(val);
      console.log(this.imageFormData.virtualization,111111111111111111111);
    },
    // 获取系统版本信息
    getImageType () {
      let params = {
        osType: this.imageFormData.osType,
        virtType: this.imageFormData.virtualization,
      }
      if (!this.imageFormData.virtualization) return;
      getImageType(params).then(res => {
        if (res.data.code == 1) {
          this.systemVersion = res.data.data.items
        } else {
        this.$Message.error(res.message)  
        }
      }).catch(error => {
          this.$Message.error(error)  
      })    
    },
    getProfileName (id) { //收集profileName
      let result = this.profileList.find(item => {
        return item.id == id
      })
      if (result) {
        this.imageFormData.profileName = result.osName
      }
    },
    openSystem (data) { //点击详情的回调
      this.systemData = data;
      this.styState = true;
    },
    // 设置高度
    setStyle () {
      window.fullHeight = document.documentElement.clientHeight;
      window.fullWidth = document.documentElement.clientWidth;
      this.fullHeight = window.fullHeight;
      this.fullWidth = window.fullWidth;
      this.setTableHei = this.fullHeight - 197
      this.imagePageSize = Math.floor(this.setTableHei / 96) || 1
    },
    // 镜像列表
    getImageList (isRefresh) {
      if (!isRefresh) { // 非刷新操作才需要展示等待中的画面
        this.imageListLoading = true
        this.showDefImg = true
        this.showImgList = false
      }
      clearTimeout(this.proSetInterval)
      this.saveTargetStatusArr = []
      let query = {
        pageIndex: this.imagePage,
        pageSize: this.imagePageSize,
      }
      let params = {
        visibility: this.imageLocalvisibility,
        imageName: this.searchImageName,
        self: this.creatByMeModal ? "1" : "",
        osType: this.systemType,
        virtualization: this.virtualization,
        rangeId: this.rangeId
      }
      getImageData(params, query)
        .then(async res => {
          if (res.data.code == 1) {
            let getData = res.data.data;
            let items = getData.items
            this.imageTotal = Number(getData.total);
            items.forEach((item => {
              item.status == 'saving' ? this.$set(item, 'statusCHName', '创建中') : item.status == 'create_ing' ? this.$set(item, 'statusCHName', '镜像生成中') : item.status == 'error' ? this.$set(item, 'statusCHName', '创建失败') : this.$set(item, 'statusCHName', '创建成功')
              item.verify == 'none' ? this.$set(item, 'statusName', '未验证') : item.verify == 'NONE' ? this.$set(item, 'statusName', '未验证') : item.verify == 'verify_ing' ? this.$set(item, 'statusName', '开始验证') : item.verify == 'error' ? this.$set(item, 'statusName', '验证失败') : item.verify == 'active' ? this.$set(item, 'statusName', '验证成功') : this.$set(item, 'statusName', '验证中')
              if (item.status == 'saving' || item.status == 'create_ing' || item.verify == 'verify_ing' || item.verify == 'testing' || item.verify == 'test_complete') {
                this.saveTargetStatusArr.push(item)
              }
            }))
            if (this.saveTargetStatusArr.length > 0) {
              this.proSetInterval = setTimeout(() => {
                this.getImageList(true)
              }, 5000)
            } else {
              clearTimeout(this.proSetInterval)
            }
            await this.getReportedStatus_mixins(items).then()
            this.imageList = items

            if (items && items.length) {
              let questionIds = this.selectImages.map(icon => icon.id)
              let checkedNum = 0
              this.imageList.forEach(icon => {
                if (questionIds.includes(icon.id)) {
                  this.$set(icon, '_checked', true)
                  checkedNum++
                } else {
                  this.$set(icon, '_checked', false)
                }
              })
              if (checkedNum && this.imageList.length === checkedNum) {
                this.selectAllImages = true;
              } else {
                this.selectAllImages = false;
              }
            }
            if (items.length > 0) {
              this.showDefImg = false
              this.showImgList = true
            } else {
              this.showDefImg = true
              this.showImgList = false
            }
            this.setMainOrBranch()
          } else {
            this.imageList = []
            this.imageTotal = 0
            this.showDefImg = true
            this.showImgList = false
          }
          this.imageListLoading = false
        })
        .catch(err => {
          this.imageListLoading = false
          this.showDefImg = true
          this.showImgList = false
        })
    },
    searchCreatedByMe (val) {
      this.imagePage = 1
      this.getImageList()
    },
    searchImageNameBtn () {
      this.imagePage = 1
      let searchName = $.trim(this.imageModelInput)
      this.searchImageName = searchName;
      this.getImageList();
    },
    selectImageTypeChange (val) {
      this.imagePage = 1
      this.imageLocalvisibility = val
      this.getImageList()
    },
    selectsystemType () {
      this.imagePage = 1
      this.getImageList()
    },
    selectvtype () {
      this.imagePage = 1
      this.getImageList()
    },
    imageOnChange (val) {
      this.imagePage = val;
      this.getImageList();
    },
    // 创建镜像的回调
    creatImage () {
      this.isCreate = true
      this.showUploadFile = true
      this.modalTitle = '创建镜像'
      this.getProfileData()
      this.imageModal = true
      this.speed = 0
      this.loaded = 0
      this.fileSize = 0
      if (!this.filedArr.length) {
        this.flag = 0 //清空标志位,防止进度条错乱
        this.progress = 0 // 重置进度条
      }
      this.filedArr.length ? this.setDisabled = true : this.setDisabled = false
    },
    modifyImage (item) { //修改按钮的回调
      this.modalTitle = '修改镜像'
      this.isCreate = false
      this.imageID = item.id
      this.showUploadFile = false
      this.getImageInfo()
      this.getProfileData()
      this.imageModal = true
    },
    // 监控modal状态
    watchModalStatus (val) {
      if (!val) {
        this.creatImageHandleReset('imageFormData')
      }
    },
    // 获取镜像数据 回显
    getImageInfo () {
      getDetailByID(this.imageID)
        .then(res => {
          if (res.data.code === 1) {
            let imageDate = res.data.data
            this.imageFormData.imageName = imageDate.imageName;
            this.imageFormData.minDisk = imageDate.minDisk;
            this.imageFormData.minRam = imageDate.minRam;
            this.imageFormData.profileId = imageDate.profileId;
            this.imageFormData.profileName = imageDate.profileName
            this.imageFormData.osType = imageDate.osType;
            this.imageFormData.virtualization = imageDate.virtualization;
            this.imageFormData.visibility = imageDate.visibility;
            this.imageFormData.nodeType = imageDate.nodeType.split(',');
            this.imageFormData.hasQga = imageDate.qga;
            this.imageFormData.hasVirtoDriver = imageDate.virtio;
            this.imageFormData.htPlug = imageDate.htPlug ? imageDate.htPlug : false;
            this.imageFormData.hasCloudInit = imageDate.cloud;
            this.imageFormData.description = imageDate.description;
            this.imageFormData.hwVifModel = imageDate.hwVifModel ? imageDate.hwVifModel : '';
            this.imageFormData.hwDiskBus = imageDate.hwDiskBus ? imageDate.hwDiskBus : '';
            this.imageFormData.osVersion = imageDate.osVersion
            this.getImageType()
          }
        })
        .catch(err => {
        })
    },
    // 获取 profile 列表
    getProfileData () {
      getProfile()
        .then(res => {
          if (res.data.code == 1) {
            let profiles = res.data.data;
            profiles.forEach(item => {
              item.id = item.id + ''
            })
            this.profileList = profiles;
          } else {
            this.$Message.error('获取镜像列表失败！')
          }
        })
        .catch(err => {
          this.$Message.error('服务连接失败！')
        })

    },
    // 提交镜像
    submitBtn (name) {
      if (this.isCreate) {
        this.creatImageHandleSubmit(name)
      } else {
        this.modifySubmitImage(name)
      }
    },
    creatImageHandleSubmit (name) {
      let _this = this
      this.$refs[name].validate((valid) => {
        if (valid) {
          let param = {
            imageName: _this.imageFormData.imageName,
            minDisk: _this.imageFormData.minDisk + '',
            minRam: _this.imageFormData.minRam + '',
            visibility: _this.imageFormData.visibility,
            virtualization: _this.imageFormData.virtualization,
            nodeType: _this.imageFormData.nodeType.join(','),
            osType: _this.imageFormData.osType,
            qga: _this.imageFormData.hasQga + '',
            cloud: _this.imageFormData.hasCloudInit + '',
            virtio: _this.imageFormData.hasVirtoDriver + '',
            htPlug: _this.imageFormData.htPlug + '',
            description: _this.imageFormData.description,
            profileId: _this.imageFormData.profileId,
            profileName: _this.imageFormData.profileName,
            tempId: _this.imageFormData.tempId,
            osVersion:_this.imageFormData.osVersion
          }
          for (let key in param) {
            if (!param[key]) {
              param[key] = null
            }
          }
          if (!this.progressflag) {
            this.$Message.error('请选择文件上传！')
            return
          }
          // let params = _this.$Qs.stringify(param, { skipNulls: true })
          _this.addImageBtnLoading = true
          _this.setDisabled = true
          _this.axios({
            method: 'post',
            url: `${_this.updateUrl}`,
            data: param,
            headers: {
              'Content-type': 'application/json',
            },
          })
            .then(res => {
              if (res.data.code == 1) {
                this.imageFormData.file = null
                this.imageModal = false
                this.setDisabled = false
                this.addImageBtnLoading = false
                this.refreshImage()
                this.$Notice.info({
                  title: '镜像消息通知',
                  desc: '镜像上传完成，更新到云服务器仍需要3到5分钟，请在之后刷新镜像列表查看',
                  duration: 0
                });
              }
            })
            .catch(err => {
              _this.$Message.error('服务器连接失败！')
              _this.addImageBtnLoading = false
              _this.setDisabled = false
            })
        } else {
          this.$Message.error('请完善信息！');
        }
      })
    },
    creatImageHandleReset (name) {
      if (this.filedArr.length) {
        this.$Message.warning({ content: '请等待当前文件上传,或者刷新页面重新上传', duration: 5 })
      } else {
        this.progressflag = false
        this.flag = 0 //清空标志位,防止进度条错乱
        this.progress = 0 // 重置进度条
      }
      this.$refs[name].resetFields();
    },
    handleUpload (file) {
      this.progressflag = true
      this.flag = 0 //清空标志位,防止进度条错乱
      this.progress = 0 // 重置进度条
      let fileType = this.imageFormData.virtualization=='kvm'?['qcow2', 'QCOW2']:['TAR', 'tar', 'docker', 'DOCKER']
      // 新加上传过程
      if (file) {
        if (!file.name.includes('.')) {
          this.$Message.error({ content: '请添加文件类型后缀', duration: 5 })
          return false
        }
        let FileExt = file.name.replace(/.+\./, "");//取得文件的后缀名
        let newName = file.name.replace('.' + FileExt, '') //取得文件除了后缀之外的名字
        if (!fileType.includes(FileExt)) {   // 添加上传的镜像文件类型验证
          this.progressflag = false //关闭文件上传进度展示
          this.$Message.error({ content: this.imageFormData.virtualization=='kvm'?'kvm类型文件格式为 XX.qcow2':'docker类型文件格式为 XX.docker  和 XXX.tar', duration: 5, closable: true })
          return false
        }
        let virtualization = JSON.parse(JSON.stringify(this.imageFormData.virtualization))
        if (FileExt == 'qcow2' || FileExt == 'QCOW2') {
          this.imageFormData.virtualization = 'kvm'
        } else if (FileExt == 'docker' || FileExt == 'DOCKER') {
          this.imageFormData.virtualization = 'docker'
        }
        if (virtualization != this.imageFormData.virtualization) {
          this.imageFormData.osVersion = ''
          this.getImageType()
        }
        let Newfile = new File([file], newName, {
          type: file.type
        })
        if (file.size > 1024 * 1024) {
          this.fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'
        } else {
          this.fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'
        }
        this.imageFormData.file = Newfile;
        this.upload(file)
      }

      return false;
    },
    upload (file) {
      if (file.size <= 0) {
        this.$Message.error({
          content: '无效文件!',
          duration: 3
        })
        this.progressflag = false
        return
      }
      this.setDisabled = true //禁用选择文件按钮和提交按钮
      this.filedArr = []
      var clientId = this.generateClientId() //id
      var fileName = file.name;
      var size = file.size
      // if (file.size < 1024 * 1024 * 600) {
        // var shardSize = file.size; //如果上传的文件小于600M直接以当前文件为一个分片
      // } else {
       var shardSize = 1024 * 1024 * 50; //如果上传的文件大于600M就以50M为一个分片
      // }
      var chunks = Math.ceil(size / shardSize); //总片数
      for (var i = 0; i < chunks; ++i) {
        var start = i * shardSize; //计算每一片的起始位置
        var end = Math.min(size, start + shardSize)  //计算每一片的结束位置
        var partFile = file.slice(start, end)
        this.filedArr.push(partFile)
      };
      //上传分片请求函数
      const partUpload = async (clientId, filedArr, fileName, chunks, chunkId) => {
        try {
          let _this = this
          let partFile = filedArr[chunkId]
          var form = new FormData();
          form.append('clientId', clientId); //客户端id
          form.append('file', partFile); // slice方法 用于切出文件的一部分
          form.append('fileName', fileName); // 文件名
          form.append('chunks', chunks); // 总片数
          form.append('chunkId', chunkId); //当前是第几片
          const res = await _this.axios({
            method: 'post',
            url: `${this.baseURL}/resource-manager/upload/part`,
            data: form,
            headers: {
              'Content-type': 'multipart/form-data',
            },
            timeout:0,
            onUploadProgress: progressEvent => {
              if (file.size > 1024 * 1024) {
                this.fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'
              } else {
                this.fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'
              }
              this.fileName = file.name
              // if (file.size < 1024 * 1024 * 600) {
              //   var complete = Math.floor(progressEvent.loaded / progressEvent.total * 100)
              //   _this.progress = complete
              // }
              var newTime = +new Date()
              var DTime = (newTime - this.oldTime) / 1000
              this.oldTime = newTime

              var aaspeed = Number(progressEvent.loaded - _this.loaded) / (1024 * 1024)
              _this.loaded = progressEvent.loaded
              if (aaspeed / DTime < 1) {
                _this.speed = (Math.round(aaspeed / DTime * 1024 * 100) / 100).toString() + 'kB/s'
              } else {
                _this.speed = (Math.round(aaspeed / DTime * 100) / 100).toString() + 'MB/s'
              }
            },
          });
          if (res.data.code == 1) {
            chunkId += 1
            if (chunkId < this.filedArr.length) {
              _this.loaded = 0
              this.flag += 1
              var complete = Math.ceil(this.flag / chunks * 100)   //当前进度所占总进度的百分比
              this.progress = complete
              partUpload(clientId, this.filedArr, fileName, chunks, chunkId)
            } else {
              this.flag += 1
              var complete = Math.ceil(this.flag / chunks * 100)   //当前进度所占总进度的百分比
              this.progress = complete
              if (this.progress == 100) {
                this.setDisabled = false //打开提交和选择文件按钮权限
                _this.loaded = 0
                this.speed = 0//置空速度
                this.filedArr = []
                this.$Message.success({
                  content: '文件上传成功!',
                  duration: 3

                })
                // this.mergeFile(clientId,fileName) //不再调用合并分片接口，创建镜像的时候tempId为随机生成的clientId
                this.imageFormData.tempId = clientId
              }
            }
          }
        } catch (error) {
          console.log(error)
        }

      }
      partUpload(clientId, this.filedArr, fileName, chunks, 0)
    },
    //所有文件上传完毕之后的合并接口回调
    mergeFile (clientId, fileName) {
      var formMerge = new FormData();
      formMerge.append("clientId", clientId);
      formMerge.append("fileName", fileName);
      mergeFiles(formMerge)
        .then(res => {
          if (res.data.code == 1) {
            this.imageFormData.tempId = res.data.data
          }
        }
        ).catch(err => {
          this.$Message.error('合并文件出错')
        })
    },
    //文件的唯一ID
    generateClientId () {
      var counter = 0;
      var clientId = (+new Date()).toString(32),
        i = 0;
      for (; i < 5; i++) {
        clientId += Math.floor(Math.random() * 65535).toString(32);
      }
      return clientId + (counter++).toString(32);
    },
    // 修改镜像
    modifySubmitImage (name) {
      let _this = this
      _this.$refs[name].validate((valid) => {
        if (valid) {
          let formData = {
            imageName: _this.imageFormData.imageName,
            osType: _this.imageFormData.osType,
            description: _this.imageFormData.description,
            visibility: _this.imageFormData.visibility,
            virtualization: _this.imageFormData.virtualization,
            minDisk: _this.imageFormData.minDisk,
            minRam: _this.imageFormData.minRam,
            qga: _this.imageFormData.hasQga + '',
            virtio: _this.imageFormData.hasVirtoDriver + '',
            htPlug: _this.imageFormData.htPlug + '',
            cloud: _this.imageFormData.hasCloudInit + '',
            nodeType: _this.imageFormData.nodeType.join(','),
            //profile_id: _this.imageFormData.profileId,
            profileId: _this.imageFormData.profileId,
            profileName: _this.imageFormData.profileName,
            hwVifModel: _this.imageFormData.hwVifModel,
            hwDiskBus: _this.imageFormData.hwDiskBus,
            osVersion:_this.imageFormData.osVersion
          };
          let params = {
            id: this.imageID,
            data: formData
          }
          _this.addImageBtnLoading = true
          modifyImg(params)
            .then(res => {
              if (res.data.code == 1) {
                _this.$Message.success({
                  content: '修改成功！',
                  duration: 3,
                })
                this.imageModal = false
                this.getImageList()
              } else {
                _this.$Message.error({ content: res.data.message, duration: 5, closable: true })
              }
              _this.addImageBtnLoading = false
            })
            .catch(err => {
              _this.addImageBtnLoading = false
            })
        } else {
          _this.$Message.error('请完善信息！');
        }
      })
    },
    // 删除镜像
    delImg (item) {
      deleteImage(item.id)
        .then(res => {
          if (res.data.code == 1) {
            this.$Message.success({
              content: '删除成功！',
              duration: 3,
            })
            if (this.imagePage > 1 && this.imageList.length === 1) {
              this.imagePage -= 1
            }
            this.getImageList();
            this.distributed && this.$refs.selectTable.closeItem(item);
          } else {
            this.$Message.error({ content: res.data.message, duration: 5, closable: true })
          }
        })
        .catch(err => {
        })
    },
    // 刷新镜像
    refreshImage () {
      this.imagePage = 1
      this.searchImageName = ''
      this.imageModelInput = ''
      this.virtualization = ''
      this.imageLocalvisibility = ''
      this.systemType = ''
      this.rangeId = ''
      this.creatByMeModal = false
      this.getImageList()
    },
    // 计算index
    handleProIndex (key) {
      return (this.imagePage - 1) * this.imagePageSize + key + 1
    },
    getGb (val) {
      let floatNum = parseInt(val) / (1024 * 1024 * 1024)
      floatNum = floatNum.toFixed(2)
      return floatNum
    },
    // 设置可见范围
    setVisibility (val) {
      let obj = {}
      let text = ''
      let color = ''
      if (val === 'public') {
        text = '系统'
        color = '#4169E1'
      } else if (val === 'share') {
        text = '单位'
        color = '#32CD32'
      } else if (val === 'private') {
        text = '个人'
        color = '#FFA500'
      }
      obj.text = text
      obj.color = color
      return obj
    },
    // 设置是否可点击
    setIsClick (item) {
      if (item.visibility === 'public' || (item.creator !== this.USER_ID && !this.isRootDesinger)) {
        return true //{ 'pointer-events': 'none' }
      }
    },
    setImgSrc (item) {
      if (item.visibility === 'public' || (item.creator !== this.USER_ID && !this.isRootDesinger)) {
        return require('../../assets/project/modifys.png')
      } else {
        return require('../../assets/project/modifys-h.png')
      }
    },
    setDelImgSrc (item) {
      if (item.visibility === 'public' || (item.creator !== this.USER_ID && !this.isRootDesinger)) {
        return require('../../assets/project/delNote-d.png')
      } else {
        return require('../../assets/project/delNote-h.png')
      }
    },
    setImgUserSrc (item) {
      if (item.visibility === 'public' || (item.creator !== this.USER_ID && !this.isRootDesinger)) {
        return require('../../assets/project/invita-d.png')
      } else {
        return require('../../assets/project/invita-h.png')
      }
    },
    // 镜像用户管理
    imageUserBtn (item) {
      if (item.visibility === 'public' || (item.creator !== this.USER_ID && !this.isRootDesinger)) {
        this.$Message.error({
          content: '无操作权限！',
          duration: 3
        })
      } else {
        this.imageUserId = item.id
        this.getImageUserData(item.id)
        this.showImgUser = true
        this.formIsShow = false
        this.isClound = item.cloud
      }
    },
    // 查询镜像已接入用户
    getImageUserData (id) {
      getImageUserList(id)
        .then(res => {
          if (res.data.code === 1) {
            this.imgUserList = res.data.data
          } else {
            this.imgUserList = []
          }
        })
        .catch(err => {
          this.imgUserList = []
        })
    },
    // 增加接入账号
    showForm () {
      this.formV = {
        accessType: "ssh",
        password: "",
        imageId: "",
        port: '22',
        pwdType: this.isClound ? "cloud" : 'static',
        userName: "",
        id: '',
      }
      this.isCreatUser = true
      this.formIsShow = true
    },
    addOrModify (name) { //接入账号提交的回调
      if (this.isCreatUser) {
        this.addUserBtn(name)
      } else {
        this.modifyUser(name)
      }
    },
    resetAddUser (name) {
      this.$refs[name].resetFields();
      this.formV['pwdType'] = this.isClound ? "cloud" : 'static'
    },
    addUserBtn (name) { //创建接入账号
      this.$refs[name].validate((valid) => {
        if (valid) {
          let params = {
            accessType: this.formV.accessType,
            password: this.formV.pwdType === 'cloud' ? '' : this.formV.password,
            imageId: this.imageUserId,
            port: this.formV.accessType === 'console' ? '' : Number(this.formV.port),
            pwdType: this.formV.pwdType,
            userName: this.formV.userName,
          }
          this.addUserLoading = true
          addAccess(params)
            .then(res => {
              if (res.data.code === 1) {
                this.getImageUserData(this.imageUserId)
                this.formIsShow = false
                this.$Message.success({ content: '添加成功', duration: 3 })
              } else {
                this.$Message.error({ content: res.data.message, duration: 5, closable: true })
              }
              this.addUserLoading = false
            })
            .catch(err => {
              this.addUserLoading = false
            })
        } else {
          this.$Message.error('请完善信息');
        }
      })
    },
    // 修改接入用户
    modifyAssBtn (row) {
      this.formV = {
        accessType: row.accessType,
        password: row.password,
        imageId: row.imageId,
        port: row.port ? row.port + '' : '',
        pwdType: row.pwdType,
        userName: row.userName,
        id: row.id,
      }
      this.isCreatUser = false
      this.formIsShow = true
    },
    modifyUser (name) { //修改接入账号
      this.$refs[name].validate((valid) => {
        if (valid) {
          let params = {
            accessType: this.formV.accessType,
            password: this.formV.pwdType === 'cloud' ? '' : this.formV.password,
            imageId: this.imageUserId,
            port: this.formV.accessType === 'console' ? '' : Number(this.formV.port),
            pwdType: this.formV.pwdType,
            userName: this.formV.userName,
            id: this.formV.id,
          }
          this.addUserLoading = true
          modifyAccess(params)
            .then(res => {
              this.addUserLoading = false
              if (res.data.code === 1) {
                this.getImageUserData(this.imageUserId)
                this.formIsShow = false
                this.$Message.success({ content: '修改成功', duration: 3 })
              } else {
                this.$Message.error({ content: res.data.message, duration: 5, closable: true })
              }
            })
            .catch(err => {
              this.addUserLoading = false
            })
        } else {
          this.$Message.error('请完善信息');
        }
      })
    },
    // 删除镜像用户
    delAccess (id) {
      delAccess(id)
        .then(res => {
          if (res.data.code === 1) {
            this.getImageUserData(this.imageUserId)
            this.formIsShow = false
            this.$Message.success({ content: '删除成功', duration: 3 })
          } else {
            this.$Message.error({ content: res.data.message, duration: 5, closable: true })
          }
        })
        .catch(err => {
        })
    },
    setUserPort () {
      let accessType = this.formV.accessType
      switch (accessType) {
        case 'ssh':
          this.createPort = '22'
          this.formV.port = '22'
          break
        case 'rdp':
          this.createPort = '3389'
          this.formV.port = '3389'
          break
        case 'console':
          this.createPort = '5900'
          this.formV.port = ''
          break
        case 'telnet':
          this.createPort = '23'
          this.formV.port = '23'
          break
      }
    },
    setColor (item) {
      let color ='var(--status-pre)';
      switch (item.status) {
        case 'error':  // 创建失败
          color = 'var(--status-no)'//'#ff4242'
          return color
          break;
        case 'create_ing':  // 镜像生成中
          color = 'var(--status-ing)'//'#ff8244'
          return color
          break;
        case 'saving': // 创建中
          color = 'var(--status-ing)';
          return color;
          break;
        case 'active': // 创建成功
          color = 'var(--status-yes)';
          return color;
          break;
        default:
          return color;
      }
    },
    setScriptColor (item) {
      let color = '#ff8244';
      switch (item.verify) {
        case 'none':  // 未验证
          color = 'var(--status-pre)'//'grey'
          return color
          break;
        case 'NONE':  // 未验证
          color = 'var(--status-pre)'//'grey'
          return color
          break;
        case 'verify_ing':  // 开始验证
          color = 'var(--status-ing)'//'#ff8244'
          return color
          break;
        case 'testing':  // 验证中
          color = 'var(--status-ing)'//'#ff8244'
          return color
          break;
        case 'test_complete':  // 验证中
          color = 'var(--status-ing)'//'#ff8244'
          return color
          break;
        case 'active':  // 验证成功
          color = 'var(--status-yes)' //'#06b649'
          return color
          break;
        case 'error':  // 验证失败
          color = 'var(--status-no)'//'#ff4242'
          return color
          break;
      }
    },

    mouseOver (item) {
      this.data1 = []
      if (item.verify == 'error' || item.verify == 'active') {
        let query = {
          type: 'verify_image'
        }
        getOperateInfo(item.id, query).then(res => {
          if (res.code == 1 && res.data.msg) {
            let Obj = JSON.parse(res.data.msg)
            this.data1 = Obj
          }
        }).catch(err => {
          this.$message.error({ content: err.message, duration: 3 })
        })
      }

    },
    // 解决气泡框关闭前 表格置空时留有气泡框影子问题，
    changeFlag (item) {
      if (item.verify == 'error' || item.verify == 'active') {
        setTimeout(() => {
          this.messageSwitch = false
        }, 100)
      }

    },
    changeSwitch (item) {
      if (item.verify == 'error' || item.verify == 'active') {
        this.messageSwitch = true
      }
    },
    check (item) {
      let id = item.id
      checkImage(id).then((res) => {
        if (res.data.code == 1) {
          this.$Message.success({
            content: '操作成功',
            duration: 3
          })
          this.getImageList()
        } else {
          this.$Message.warning({
            content: res.data.message,
            duration: 3
          })
        }
      })
    },
    //选择导出图标
    handleCheckImage (e) {
      this.selectAllImages = e;
      this.imageList.forEach(icon => {
        this.checkSingleImage(e, icon);
      })
    },
    checkSingleImage (e, icon) {
      if (e && !this.selectImages.map(icon => icon.id).includes(icon.id)) {
        this.selectImages.push(icon);
      } else if (!e && this.selectImages.map(icon => icon.id).includes(icon.id)) {
        let index = this.selectImages.findIndex(item => icon.id == item.id);
        this.selectImages.splice(index, 1);
      }
      let checkudQuestion = this.imageList.find(item => item.id == icon.id)
      if (checkudQuestion) {
        this.$set(checkudQuestion, '_checked', e);
      }
      if (this.imageList.length > 0 && this.imageList.every(icon => icon._checked === true)) {
        this.selectAllImages = true;
      } else {
        this.selectAllImages = false;
      }
    },
    // 上报镜像
    reportedImages () {
      if (this.selectImages.length == 0) {
        this.$Message.warning('请选择镜像');
        return
      }
      let imageIds = []
      this.selectImages.forEach(image => {
        imageIds.push(image.id)
      });
      reportedImages(imageIds).then(({ code, message }) => {
        if (code !== 1) {
          this.$Message.warning(message)
          return
        }
        this.$Message.info('上报镜像成功')
        this.getImageList()
        this.selectImages = []
        this.selectAllImages = false
        this.imageList.forEach(item => this.$set(item, '_checked', false))
      }).catch(() => {
        this.$Message.error('上报镜像异常')
      })
    },
    //查询所有分靶场信息
    queryAllRange () {
      getRangeAll().then(res => {
        if (res.code === 1) {
         let mainRange = res.data.find(item=>{
            return  item.self=='0'
          })
          this.mainRange = mainRange.name||'选择靶场'
          this.rangeAllList = res.data
        }
      })
    },
    searchItem (val) {
      this.getImageList();
    },
    setMainOrBranch(){
        let res =  this.rangeAllList.find(item=>{
            return item.id==this.rangeId
        })
        if(res&&res.self!=0){
            this.mainRangeflag = false // 分靶场
        }else{
            this.mainRangeflag = true // 主靶场
        }
    },
  },
  beforeDestroy () {
    clearTimeout(this.proSetInterval)
  }
}
</script>
<style scoped>
#quesDetail {
  display: table;
  width: 100%;
  border: 1px solid var(--table-border);
  table-layout: fixed;
  word-break: break-all;
}
#quesDetail p {
  display: table-row;
  line-height: 36px;
  text-align: center;
}
#quesDetail p span {
  display: table-cell;
  border-bottom:1px solid var(--table-border);
}
.ios-alert {
  /* position: absolute;
        top: -44px;
        right: -404px; */
  color: orange;
  font-size: 16px;
  cursor: pointer;
}
.too {
  position: absolute;
  left: 113px;
  top: -1px;
}
</style>
